package com.ihr360.insurance.model.dto.benefits;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import com.ihr360.authority.sharing.entityhandler.UserResourceHandler;
import com.ihr360.commons.lang.DateUtils;
import com.ihr360.commons.model.IEnabledEntity;
import com.ihr360.commons.model.base.Division;
import com.ihr360.insurance.model.type.BenefitStrategy;
import com.ihr360.insurance.model.vo.BenefitGroupVo;
import com.ihr360.insurance.model.vo.CompanyBenefitConfigVo;
import com.ihr360.shared.entitywithlistener.NumberIdWithTimeAndCompanyId;
import org.apache.commons.collections.CollectionUtils;
import org.hibernate.annotations.DynamicUpdate;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 公司法定福利（社保公积金）
 * 法定福利的各项配置，默认采用MandatoryBenefitGroup中的系统配置信息
 * 当用户对
 */
@Entity
@Table
@Embeddable
@EntityListeners(value = {UserResourceHandler.class})
@DynamicUpdate
public class CompanyBenefit extends NumberIdWithTimeAndCompanyId<Long> implements IEnabledEntity {

    private static final long serialVersionUID = 5573316847565985489L;

    /**
     * 社保分组
     */
    @ManyToOne
    private MandatoryBenefitGroup group;

    /**
     * 缴纳策略
     */
    @Column(nullable = false, length = 20)
    @Enumerated(EnumType.STRING)
    private BenefitStrategy strategy = BenefitStrategy.CURRENT;

    /**
     * 名称
     */
    @Column(nullable = false, length = 150)
    private String name;

    /**
     * 是否启用
     */
    private Boolean enabled = true;

    @Column(length = 500)
    private String remark;

    /**
     * 公司法定福利方案（关于各种险种的配置信息）
     */
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "companyBenefit")
    private List<CompanyBenefitConfig> companyConfigs = new ArrayList<>();

    private Integer staffCount = 0;

    /**
     * 公积金免税比例（针对个人部分有效）
     */
//    private Integer hfTaxFreeRatio;


    public MandatoryBenefitGroup getGroup() {
        return group;
    }

    public void setGroup(MandatoryBenefitGroup group) {
        this.group = group;
    }

    public BenefitStrategy getStrategy() {
        return strategy;
    }

    public void setStrategy(BenefitStrategy strategy) {
        this.strategy = strategy;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<CompanyBenefitConfig> getCompanyConfigs() {
        return companyConfigs;
    }

    public void setCompanyConfigs(List<CompanyBenefitConfig> companyConfigs) {
        this.companyConfigs = companyConfigs;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public void setStaffCount(Integer staffCount) {
        this.staffCount = staffCount;
    }

    public Integer getStaffCount() {
        if (staffCount == null) {
            return 0;
        }
        return staffCount;
    }

    /*public Integer getHfTaxFreeRatio() {
        return hfTaxFreeRatio;
    }

    public void setHfTaxFreeRatio(Integer hfTaxFreeRatio) {
        this.hfTaxFreeRatio = hfTaxFreeRatio;
    }*/

    /******************************************提供list列表数据接口******************************************/
    @JsonIgnore
    public String getGroupModeName() {
        if (group != null) {
            MandatoryBenefitsMode mode = group.getMode();
            if (mode != null) {
                return mode.getName();
            }
        }
        return null;
    }

    @JsonIgnore
    public Long getGroupDivisionId() {
        if (group != null) {
            Division division = group.getDivision();
            if (division != null) {
                return division.getId();
            }
        }
        return null;
    }

    @JsonIgnore
    public String getGroupTemplatesTypeNames() {
        if (group != null) {
            List<MandatoryBenefitTemplate> templates = group.getTemplates();
            if (CollectionUtils.isNotEmpty(templates)) {
                StringBuilder typeNames = new StringBuilder();
                Date yearMonthDate = DateUtils.getYearMonthDate(new Date());
                templates.stream()
                        .filter(template -> template.getType() != null)
                        .forEach(template -> {
                            if (isTemplateValid(template, yearMonthDate)) {
                                typeNames.append(template.getType().getName().replace("保险", "")).append(" ");
                            }
                        });
                return typeNames.toString();
            }
        }
        return null;
    }

    private boolean isTemplateValid(MandatoryBenefitTemplate template, Date currentYearMonthDate) {
        MandatoryBenefitsType type = template.getType();
        List<PaymentConfig> configs = template.getConfigs();
        if (type == null || !type.isEnabled() || type.getName() == null || CollectionUtils.isEmpty(configs)) {
            return false;
        }
        //自定义设置优先
        if (CollectionUtils.isNotEmpty(companyConfigs)) {
            for (CompanyBenefitConfig benefitConfig : companyConfigs) {
                Date effectiveOn = benefitConfig.getEffectiveOn();
                Date invalidOn = benefitConfig.getInvalidOn();
                if (type.getId().equals(benefitConfig.getType().getId()) && isDateInRange(currentYearMonthDate, effectiveOn, invalidOn)) {
                    return benefitConfig.isEnabled();
                }
            }
        }
        //系统设置
        for (PaymentConfig config : configs) {
            Date effectiveOn = config.getEffectiveOn();
            Date invalidOn = config.getInvalidOn();
            if (isDateInRange(currentYearMonthDate, effectiveOn, invalidOn)) {
                return true;
            }
        }

        return false;
    }

    private boolean isDateInRange(Date currentYearMonthDate, Date effectiveOn, Date invalidOn) {
        return !effectiveOn.after(currentYearMonthDate)
                && (invalidOn == null || invalidOn.after(currentYearMonthDate));
    }

    /******************************************提供详情数据接口******************************************/
    @JsonIgnore
    public List<CompanyBenefitConfigVo> getVoCompanyConfigs() {
        if (CollectionUtils.isNotEmpty(companyConfigs)) {
            List<CompanyBenefitConfigVo> configs = Lists.newArrayListWithCapacity(companyConfigs.size());
            companyConfigs.forEach(config -> configs.add(new CompanyBenefitConfigVo(
                    config.getId(), config.getVoType(), config.getRemedialConfig(),
                    config.getCompanyConfig(), config.getPersonConfig(),
                    config.getEffectiveOn(), config.getInvalidOn(), config.isEnabled())));
            return configs;
        }
        return Collections.emptyList();
    }

    @JsonIgnore
    public BenefitGroupVo getVoGroup() {
        if (group != null) {
            return new BenefitGroupVo(group.getId(), group.getCategory(), group.getVoMode(),
                    this.group.getDivision(), group.isEnabled(), group.getInlineTemplates());
        }
        return null;
    }

}
